using Microsoft.Extensions.Logging;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Zhao.Common.Helper;
using Zhao.Models.DTO;
using Zhao.Models.Entity;
using Zhao.Repository.Base;
using Zhao.Repository.UnitOfWork;
using Zhao.Models.Entity;
using Zhao.IServer;
using SqlSugar.Extensions;

namespace Zhao.Service
{
    /// <summary>
    /// 结算记录服务实现
    /// </summary>
    public class SettlementRecordService : BaseService<SettlementRecord>, ISettlementRecordService
    {
        private readonly ISqlSugarClient _db;
        private readonly ILogger<SettlementRecordService> _logger;

        public SettlementRecordService(
            IBaseRepository<SettlementRecord> baseDal,
            IUnitOfWork unitOfWork,
            ISqlSugarClient db,
            ILogger<SettlementRecordService> logger)
            : base(baseDal, unitOfWork)
        {
            _db = db;
            _logger = logger;
        }

        /// <summary>
        /// 添加结算记录
        /// </summary>
        /// <param name="record">结算记录</param>
        /// <returns>结算记录ID</returns>
        public async Task<int> AddSettlementRecordAsync(SettlementRecord record)
        {
            try
            {
                // 设置创建时间
                record.CreatedAt = DateTime.Now;
                record.SettlementTime = DateTime.Now;

                // 生成结算编号
                if (string.IsNullOrEmpty(record.SettlementNo))
                {
                    record.SettlementNo = $"STL{DateTime.Now:yyyyMMddHHmmss}{new Random().Next(100, 999)}";
                }

                // 插入记录
                int id = await _Client.Insertable(record).ExecuteCommandAsync();
                return id;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "添加结算记录时发生错误");
                return 0;
            }
        }

        /// <summary>
        /// 查询结算记录
        /// </summary>
        /// <param name="queryParams">查询参数</param>
        /// <returns>分页结果</returns>
        public async Task<PageModel<SettlementRecordDto>> QuerySettlementRecordsAsync(SettlementRecordQueryParams queryParams)
        {
            try
            {
                // 获取总条数
                RefAsync<int> totalCount = 0;

                // 构建查询
                var query = _db.Queryable<SettlementRecord>()
                    .LeftJoin<Venues>((s, v) => s.VenueID == v.VenueID)
                    .LeftJoin<Activities>((s, v, a) => s.SettlementType == 1 && s.RelatedID == a.ActivityID)
                    .LeftJoin<Appointments>((s, v, a, app) => s.SettlementType == 3 && s.RelatedID == app.AppointmentID);

                // 应用过滤条件
                if (queryParams.VenueID.HasValue)
                {
                    query = query.Where((s, v, a, app) => s.VenueID == queryParams.VenueID);
                }

                if (queryParams.SettlementType.HasValue)
                {
                    query = query.Where((s, v, a, app) => s.SettlementType == queryParams.SettlementType);
                }

                if (queryParams.Status.HasValue)
                {
                    query = query.Where((s, v, a, app) => s.Status == queryParams.Status);
                }

                if (queryParams.StartTime.HasValue)
                {
                    query = query.Where((s, v, a, app) => s.SettlementTime >= queryParams.StartTime);
                }

                if (queryParams.EndTime.HasValue)
                {
                    // 结束日期加1天，以便包含整个结束日期
                    var endTime = queryParams.EndTime.Value.AddDays(1);
                    query = query.Where((s, v, a, app) => s.SettlementTime < endTime);
                }

                if (!string.IsNullOrEmpty(queryParams.Keyword))
                {
                    query = query.Where((s, v, a, app) =>
                        s.SettlementNo.Contains(queryParams.Keyword) ||
                        s.Description.Contains(queryParams.Keyword));
                }

                // 执行查询
                var list = await query
                    .OrderByDescending((s, v, a, app) => s.SettlementTime)
                    .Select((s, v, a, app) => new SettlementRecordDto
                    {
                        SettlementID = s.SettlementID,
                        SettlementType = s.SettlementType,
                        SettlementTypeName = s.SettlementType == 1 ? "活动结算" : "预约结算",
                        RelatedID = s.RelatedID,
                        VenueID = s.VenueID,
                        VenueName = v.VenueName,
                        RelatedName = s.SettlementType == 1
                            ? a.Title
                            : SqlFunc.IIF(app.FieldID > 0, $"场地{app.FieldID}", "未知"),
                        Amount = s.Amount,
                        SettlementTime = s.SettlementTime,
                        Status = s.Status,
                        StatusName = s.Status == 1 ? "成功" : "失败",
                        OrderID = s.OrderID,
                        BillID = s.BillID,
                        Description = s.Description,
                        SettlementNo = s.SettlementNo
                    })
                    .ToPageListAsync(queryParams.PageIndex, queryParams.PageSize, totalCount);

                // 计算总页数
                int totalPages = (int)Math.Ceiling(totalCount.ObjToDecimal() / queryParams.PageSize.ObjToDecimal());

                // 构建分页结果
                return new PageModel<SettlementRecordDto>
                {
                    PageIndex = queryParams.PageIndex,
                    PageSize = queryParams.PageSize,
                    PageCount = totalPages,
                    count = totalCount,
                    data = list,
                    code = totalCount == 0 ? -1 : 0,
                    msg = totalCount == 0 ? "未查询到任何数据" : ""
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "查询结算记录时发生错误");
                return new PageModel<SettlementRecordDto>
                {
                    code = -1,
                    msg = "查询失败：" + ex.Message,
                    data = new List<SettlementRecordDto>()
                };
            }
        }

        /// <summary>
        /// 根据ID获取结算记录详情
        /// </summary>
        /// <param name="settlementId">结算ID</param>
        /// <returns>结算记录详情</returns>
        public async Task<ApiResult<SettlementRecordDto>> GetSettlementRecordByIdAsync(int settlementId)
        {
            var result = new ApiResult<SettlementRecordDto>();

            try
            {
                var record = await _db.Queryable<SettlementRecord>()
                    .LeftJoin<Venues>((s, v) => s.VenueID == v.VenueID)
                    .LeftJoin<Activities>((s, v, a) => s.SettlementType == 1 && s.RelatedID == a.ActivityID)
                    .LeftJoin<Appointments>((s, v, a, app) => s.SettlementType == 3 && s.RelatedID == app.AppointmentID)
                    .Where((s, v, a, app) => s.SettlementID == settlementId)
                    .Select((s, v, a, app) => new SettlementRecordDto
                    {
                        SettlementID = s.SettlementID,
                        SettlementType = s.SettlementType,
                        SettlementTypeName = s.SettlementType == 1 ? "活动结算" : "预约结算",
                        RelatedID = s.RelatedID,
                        VenueID = s.VenueID,
                        VenueName = v.VenueName,
                        RelatedName = s.SettlementType == 1
                            ? a.Title
                            : SqlFunc.IIF(app.FieldID > 0, $"场地{app.FieldID}", "未知"),
                        Amount = s.Amount,
                        SettlementTime = s.SettlementTime,
                        Status = s.Status,
                        StatusName = s.Status == 1 ? "成功" : "失败",
                        OrderID = s.OrderID,
                        BillID = s.BillID,
                        Description = s.Description,
                        SettlementNo = s.SettlementNo
                    })
                    .FirstAsync();

                if (record != null)
                {
                    result.Success = true;
                    result.StatusCode = 200;
                    result.Message = "获取成功";
                    result.Data = record;
                }
                else
                {
                    result.Success = false;
                    result.StatusCode = 404;
                    result.Message = "未找到结算记录";
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取结算记录详情时发生错误");
                result.Success = false;
                result.StatusCode = 500;
                result.Message = "获取失败：" + ex.Message;
            }

            return result;
        }

        /// <summary>
        /// 获取场馆结算统计
        /// </summary>
        /// <param name="venueId">场馆ID</param>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <returns>统计结果</returns>
        public async Task<ApiResult> GetVenueSettlementStatsAsync(Guid venueId, DateTime? startTime = null, DateTime? endTime = null)
        {
            var result = new ApiResult<object>();

            try
            {
                // 构建查询
                var query = _db.Queryable<SettlementRecord>()
                    .Where(s => s.VenueID == venueId && s.Status == 1); // 只统计成功的结算

                // 应用时间过滤
                if (startTime.HasValue)
                {
                    query = query.Where(s => s.SettlementTime >= startTime.Value);
                }

                if (endTime.HasValue)
                {
                    // 结束日期加1天，以便包含整个结束日期
                    var end = endTime.Value.AddDays(1);
                    query = query.Where(s => s.SettlementTime < end);
                }

                // 统计总金额
                var totalAmount = await query.SumAsync(s => s.Amount);

                // 统计活动结算金额
                var activityAmount = await query.Where(s => s.SettlementType == 1).SumAsync(s => s.Amount);

                // 统计预约结算金额
                var appointmentAmount = await query.Where(s => s.SettlementType == 3).SumAsync(s => s.Amount);

                // 统计总记录数
                var totalCount = await query.CountAsync();

                // 统计活动结算数量
                var activityCount = await query.Where(s => s.SettlementType == 1).CountAsync();

                // 统计预约结算数量
                var appointmentCount = await query.Where(s => s.SettlementType == 3).CountAsync();

                // 构建结果
                var statsData = new
                {
                    TotalAmount = totalAmount,
                    ActivityAmount = activityAmount,
                    AppointmentAmount = appointmentAmount,
                    TotalCount = totalCount,
                    ActivityCount = activityCount,
                    AppointmentCount = appointmentCount,
                    StartTime = startTime,
                    EndTime = endTime
                };

                result.Success = true;
                result.StatusCode = 200;
                result.Message = "获取统计信息成功";
                result.Data = statsData;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取场馆结算统计时发生错误");
                result.Success = false;
                result.StatusCode = 500;
                result.Message = "获取统计信息失败：" + ex.Message;
            }

            return result;
        }

        /// <summary>
        /// 查询场地预约的结算记录
        /// </summary>
        /// <param name="queryParams">查询参数</param>
        /// <returns>分页结果</returns>
        public async Task<PageModel<FieldSettlementRecordDto>> QueryFieldSettlementRecordsAsync(SettlementRecordQueryParams queryParams)
        {
            try
            {
                // 获取总条数
                RefAsync<int> totalCount = 0;

                // 构建查询 - 仅查询场地预约结算记录 (SettlementType = 3)
                var query = _db.Queryable<SettlementRecord>()
                    .LeftJoin<Venues>((s, v) => s.VenueID == v.VenueID)
                    .LeftJoin<Appointments>((s, v, app) => s.RelatedID == app.AppointmentID)
                    .LeftJoin<Fields>((s, v, app, f) => app.FieldID == f.FieldID)
                    .Where((s) => s.SettlementType == 3); // 预约结算

                // 应用过滤条件
                if (queryParams.VenueID.HasValue)
                {
                    query = query.Where((s) => s.VenueID == queryParams.VenueID);
                }

                if (queryParams.Status.HasValue)
                {
                    query = query.Where((s) => s.Status == queryParams.Status);
                }

                if (queryParams.StartTime.HasValue)
                {
                    query = query.Where((s) => s.SettlementTime >= queryParams.StartTime);
                }

                if (queryParams.EndTime.HasValue)
                {
                    // 结束日期加1天，以便包含整个结束日期
                    var endTime = queryParams.EndTime.Value.AddDays(1);
                    query = query.Where((s) => s.SettlementTime < endTime);
                }

                if (!string.IsNullOrEmpty(queryParams.Keyword))
                {
                    query = query.Where((s) =>
                        s.SettlementNo.Contains(queryParams.Keyword) ||
                        s.Description.Contains(queryParams.Keyword));
                }

                // 执行查询
                var list = await query
                    .OrderByDescending((s) => s.SettlementTime)
                    .Select((s, v, app, f) => new FieldSettlementRecordDto
                    {
                        SettlementID = s.SettlementID,
                        SettlementType = s.SettlementType,
                        SettlementTypeName = "场地预约结算",
                        RelatedID = s.RelatedID,
                        VenueID = s.VenueID,
                        VenueName = v.VenueName,
                        RelatedName = SqlFunc.IIF(f.FieldID > 0, f.FieldName, "未知场地"),
                        Amount = s.Amount,
                        SettlementTime = s.SettlementTime,
                        Status = s.Status,
                        StatusName = s.Status == 1 ? "成功" : "失败",
                        OrderID = s.OrderID,
                        BillID = s.BillID,
                        Description = s.Description,
                        SettlementNo = s.SettlementNo,
                        //AppointmentDate = app.DisplayDate,
                        FieldID = app.FieldID,
                        FieldName = f.FieldName
                    })
                    .ToPageListAsync(queryParams.PageIndex, queryParams.PageSize, totalCount);

                // 计算总页数
                int totalPages = (int)Math.Ceiling(totalCount.ObjToDecimal() / queryParams.PageSize.ObjToDecimal());

                // 构建分页结果
                return new PageModel<FieldSettlementRecordDto>
                {
                    PageIndex = queryParams.PageIndex,
                    PageSize = queryParams.PageSize,
                    PageCount = totalPages,
                    count = totalCount,
                    data = list,
                    code = totalCount == 0 ? -1 : 0,
                    msg = totalCount == 0 ? "未查询到任何场地预约结算记录" : ""
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "查询场地预约结算记录时发生错误");
                return new PageModel<FieldSettlementRecordDto>
                {
                    code = -1,
                    msg = "查询失败：" + ex.Message,
                    data = new List<FieldSettlementRecordDto>()
                };
            }
        }

        /// <summary>
        /// 查询活动的结算记录
        /// </summary>
        /// <param name="queryParams">查询参数</param>
        /// <returns>分页结果</returns>
        public async Task<PageModel<ActivitySettlementRecordDto>> QueryActivitySettlementRecordsAsync(SettlementRecordQueryParams queryParams)
        {
            try
            {
                // 获取总条数
                RefAsync<int> totalCount = 0;

                // 构建查询 - 仅查询活动结算记录 (SettlementType = 1)
                var query = _db.Queryable<SettlementRecord>()
                    .LeftJoin<Venues>((s, v) => s.VenueID == v.VenueID)
                    .LeftJoin<Activities>((s, v, a) => s.RelatedID == a.ActivityID)
                    .Where((s) => s.SettlementType == 1); // 活动结算

                // 应用过滤条件
                if (queryParams.VenueID.HasValue)
                {
                    query = query.Where((s) => s.VenueID == queryParams.VenueID);
                }

                if (queryParams.Status.HasValue)
                {
                    query = query.Where((s) => s.Status == queryParams.Status);
                }

                if (queryParams.StartTime.HasValue)
                {
                    query = query.Where((s) => s.SettlementTime >= queryParams.StartTime);
                }

                if (queryParams.EndTime.HasValue)
                {
                    // 结束日期加1天，以便包含整个结束日期
                    var endTime = queryParams.EndTime.Value.AddDays(1);
                    query = query.Where((s) => s.SettlementTime < endTime);
                }

                if (!string.IsNullOrEmpty(queryParams.Keyword))
                {
                    query = query.Where((s) =>
                        s.SettlementNo.Contains(queryParams.Keyword) ||
                        s.Description.Contains(queryParams.Keyword));
                }

                // 执行查询
                var list = await query
                    .OrderByDescending((s) => s.SettlementTime)
                    .Select((s, v, a) => new ActivitySettlementRecordDto
                    {
                        SettlementID = s.SettlementID,
                        SettlementType = s.SettlementType,
                        SettlementTypeName = "活动结算",
                        RelatedID = s.RelatedID,
                        VenueID = s.VenueID,
                        VenueName = v.VenueName,
                        RelatedName = a.Title,
                        Amount = s.Amount,
                        SettlementTime = s.SettlementTime,
                        Status = s.Status,
                        StatusName = s.Status == 1 ? "成功" : "失败",
                        OrderID = s.OrderID,
                        BillID = s.BillID,
                        Description = s.Description,
                        SettlementNo = s.SettlementNo,
                        ActivityTitle = a.Title,
                        //ActivityDate = a.DisplayDate,
                        ActivityPrice = a.Price
                    })
                    .ToPageListAsync(queryParams.PageIndex, queryParams.PageSize, totalCount);

                // 计算总页数
                int totalPages = (int)Math.Ceiling(totalCount.ObjToDecimal() / queryParams.PageSize.ObjToDecimal());

                // 构建分页结果
                return new PageModel<ActivitySettlementRecordDto>
                {
                    PageIndex = queryParams.PageIndex,
                    PageSize = queryParams.PageSize,
                    PageCount = totalPages,
                    count = totalCount,
                    data = list,
                    code = totalCount == 0 ? -1 : 0,
                    msg = totalCount == 0 ? "未查询到任何活动结算记录" : ""
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "查询活动结算记录时发生错误");
                return new PageModel<ActivitySettlementRecordDto>
                {
                    code = -1,
                    msg = "查询失败：" + ex.Message,
                    data = new List<ActivitySettlementRecordDto>()
                };
            }
        }
    }
}